package com.voucher.qiege.one;

import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.Header;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

public class FileDownloader {
    private static final Map<String, String> MIME_TO_EXTENSION = new HashMap<>();

    static {
        // 文档类型
        MIME_TO_EXTENSION.put("application/pdf", "pdf");
        MIME_TO_EXTENSION.put("application/msword", "doc");
        MIME_TO_EXTENSION.put("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx");
        MIME_TO_EXTENSION.put("application/vnd.ms-excel", "xls");
        MIME_TO_EXTENSION.put("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx");
        // 图片类型
        MIME_TO_EXTENSION.put("image/jpeg", "jpg");
        MIME_TO_EXTENSION.put("image/png", "png");
        MIME_TO_EXTENSION.put("image/gif", "gif");
        MIME_TO_EXTENSION.put("image/webp", "webp");
        MIME_TO_EXTENSION.put("text/html;charset=UTF-8", "html");
        // 默认流类型
        MIME_TO_EXTENSION.put("application/octet-stream", "bin");
    }

    private static String getFileExtensionFromMime(String mime) {
        System.out.println("MIME: " + mime);
        return MIME_TO_EXTENSION.getOrDefault(mime.split(";")[0].trim(), "bin");
    }

    public static void download(String fdId, String baseSaveDir) throws Exception {
        CloseableHttpClient client = SessionManager.getClient();
//        String downloadUrl = String.format(
//                "http://oa.mexingroup.com:9999/sys/attachment/sys_att_main/sysAttMain.do" +
//                        "?method=download&fdId=%s&downloadFlag=%d",
//                URLEncoder.encode(fdId, "UTF-8"),
//                System.currentTimeMillis()
//        );
        String downloadUrl = "http://oa.mexingroup.com:9999/sys/attachment/sys_att_main/sysAttMain.do"
                + "?method=download"
                + "&fdId=" + URLEncoder.encode(fdId, "UTF-8")
                + "&downloadType=manual"
                + "&downloadFlag=" + System.currentTimeMillis();
        HttpGet downloadRequest = new HttpGet(downloadUrl);
//        downloadRequest.addHeader("Referer", "http://oa.mexingroup.com:9999/main.do");

        try (CloseableHttpResponse response = client.execute(downloadRequest)) {
            validateResponse(response); // 验证是否为合法文件响应

            // 获取输出路径
            String fileName = determineFileName(response);
            System.out.println("文件名: " + fileName);
            String savePath = Paths.get(baseSaveDir, fileName).toString();

            // 写入文件
            try (InputStream is = response.getEntity().getContent();
                 FileOutputStream fos = new FileOutputStream(savePath)) {
                byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, bytesRead);
                }
            }
            System.out.println("成功保存至: " + savePath);
        }
    }

    private static void validateResponse(CloseableHttpResponse response) throws IOException {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != 200) {
            throw new RuntimeException("HTTP错误状态码: " + statusCode);
        }
        Header ct = response.getFirstHeader("Content-Type");
        System.out.println("Content-Type: " + ct.getValue());
        if (ct == null) {
            throw new RuntimeException("无Content-Type头");
        }
    }

    private static String determineFileName(CloseableHttpResponse response) {
        // 1. 从Header提取原始文件名
        Header disposition = response.getFirstHeader("Content-Disposition");
        String rawFileName = parseContentDisposition(
                disposition != null ? disposition.getValue() : null
        );

        // 2. 容错处理
        if (rawFileName == null) {
            String mimeType = response.getFirstHeader("Content-Type").getValue();
            return generateDefaultFileName(mimeType);
        }

        // 3. 清理编码问题
        String sanitized = sanitizeFilename(rawFileName);

        // 4. 替换非法字符
        return sanitized.replaceAll("[\\\\/:*?\"<>|]", "_");
    }


    // 解析RFC 5987编码的文件名 (例如 filename*=UTF-8''filename.txt)
    private static String parseContentDisposition(String contentDisposition) {
        if (contentDisposition == null) {
            return null;
        }
        try {
            // 优先级1: 匹配RFC 5987编码文件名 (filename*=UTF-8''xxxx)
            String filename = parseRFC5987Filename(contentDisposition);
            if (filename != null) {
                return filename;
            }

            // 优先级2: 普通文件名 (filename="...")
            filename = parseStandardFilename(contentDisposition);
            if (filename != null) {
                return URLDecoder.decode(filename, StandardCharsets.UTF_8.name());
            }
            return null;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("UTF-8 not supported", e);
        }
    }
    private static String parseRFC5987Filename(String header) throws UnsupportedEncodingException {
        Matcher m = Pattern.compile("filename\\*\\s*=\\s*([^']+)'[^']*'(.*?)(?:;|$)").matcher(header);
        if (m.find()) {
            String encoding = m.group(1);
            String encodedName = m.group(2).replaceAll("\\s+", "");
            if ("UTF-8".equalsIgnoreCase(encoding)) {
                return URLDecoder.decode(encodedName, "UTF-8");
            }
        }
        return null;
    }

    private static String parseStandardFilename(String header) {
        Matcher m = Pattern.compile("filename\\s*=\\s*\"?([^;\"]+)\"?").matcher(header);
        return m.find() ? m.group(1) : null;
    }
    private static String generateDefaultFileName(String mimeType) {
        if (mimeType == "text/html;charset=UTF-8") {
            return "error.html";
        }
        String ext = getFileExtensionFromMime(mimeType);
        String timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
        return "download_" + timestamp + "." + ext;
    }
    private static String sanitizeFilename(String rawName) {
        try {
            // 尝试从ISO-8859-1转换到UTF-8（处理错误编码的中文）
            byte[] isoBytes = rawName.getBytes(StandardCharsets.ISO_8859_1);
            return new String(isoBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            return rawName.replaceAll("[^\\w.-]", "_");
        }
    }

}
